package com.guhecloud.step.definition.runtime;

import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.RejectedExecutionException;

public class StepsExecTemplate<Step extends IDomainStep,Model extends IDomainModel> {
    private static final Set<String> emptyAsyncSteps = Collections.emptySet();


    private static final List<String> emptyRevisedSteps = Collections.emptyList();

    private static final int MAX_STEP_REVISIONS = 100;

    protected void beforeStep(Step step, Model model) {
    }

    protected void afterStep(Step step, Model model) {
    }


    public final void execute(String activityCode, List<String> stepCodes, Model model) throws RuntimeException {
        if (stepCodes == null || stepCodes.isEmpty()) {
            return;
        }

        int stepRevisions = 0;
        while (++stepRevisions < MAX_STEP_REVISIONS) {
            // 执行步骤的过程中，可能会产生修订步骤逻辑
            stepCodes = executeSteps(activityCode, stepCodes, model);
            if (stepCodes.isEmpty()) {
                // 不再有步骤修订了：所有步骤都执行完毕
                break;
            }

            // 修订了后续步骤，记录个日志，then next loop
        }
    }

    private List<String> executeSteps(String activityCode, List<String> stepCodes,  Model model) throws RuntimeException {
        List<Step> steps = Center.findSteps(activityCode, stepCodes);
        try {
            for (Step step : steps) {
                beforeStep(step, model);
                step.execute(model);
                afterStep(step, model);
            }
        } catch (Exception cause) {
            if (cause instanceof RejectedExecutionException) {
                throw (RejectedExecutionException) cause;
            }
            throw cause;
        }

        return emptyRevisedSteps;
    }
}
